package com.qf.fmall2204.orders.service.impl;

import com.qf.fmall2204.orders.entity.OrderItem;
import com.qf.fmall2204.orders.entity.Orders;
import com.qf.fmall2204.orders.mapper.OrdersMapper;
import com.qf.fmall2204.orders.service.IOrderItemService;
import com.qf.fmall2204.orders.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.fmall2204.product.entity.ProductSku;
import com.qf.fmall2204.product.mapper.ProductSkuMapper;
import com.qf.fmall2204.shopcart.entity.ShoppingCart;
import com.qf.fmall2204.shopcart.service.IShoppingCartService;
import com.qf.fmall2204.websocket.OrderStatusWebSocket;
import com.qf.fmall2204.wxpay.WxPayUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单  服务实现类
 * </p>
 *
 * @author dong
 * @since 2023-04-25
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {

    @Autowired
    IShoppingCartService shoppingCartService;

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    ProductSkuMapper productSkuMapper;

    @Autowired
    IOrderItemService orderItemService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map<String, Object> add(Integer[] cids, Orders orders) throws Exception {

        //1. 查询用户购物车中的对应的商品套餐库存量是否还足够
        // 如果库存够，则继续下单流程；如果库存量不足，直接抛出异常;任何一个商品的库存不足都算失败
        List<ShoppingCart> shoppingCartList = shoppingCartService.listbycids(cids);
        // 检查库存是否足够，如果库存足够，就口径库存
        checkStock(shoppingCartList);

        //2. 生成唯一的订单编号
        String orderId = UUID.randomUUID().toString().replaceAll("-", "");

        //3. 生成订单主表（orders表）中的数据
        orders.setOrderId(orderId);

        // 产品名称：untitled
        // List<ShoppingCart> ==> List<商品名字>
        String productNames = shoppingCartList
                .stream()
                .map(ShoppingCart::getProductName)
                .distinct()
                // 把流中的字符串拼接成一个字符串
                .collect(Collectors.joining(","));
        orders.setUntitled(productNames);

        // 订单的状态，初始值1，待付款 status
        orders.setStatus("1");

        // 逻辑删除状态，初始值为0 delete_status
        orders.setDeleteStatus(0);

        // create_time
        Date date = new Date();
        orders.setCreateTime(date);

        // update_time
        orders.setUpdateTime(date);

        this.save(orders); // 入库

        //4. 生成订单明细表的数据 （OrderItem表）
        // 购物车中有几条数据，订单明细表中就有几条数据

        // List<ShoppingCart> ===> List<OrderItem>
        List<OrderItem> orderItemList = shoppingCartList.stream()
                .map(new Function<ShoppingCart, OrderItem>() {
                    @Override
                    public OrderItem apply(ShoppingCart cart) {

                        OrderItem orderItem = new OrderItem();
                        // 设置主键
                        String orderItemId = UUID.randomUUID().toString().replaceAll("-", "");
                        orderItem.setItemId(orderItemId);
                        // 设置订单id
                        orderItem.setOrderId(orderId);

                        // copy同名属性
                        BeanUtils.copyProperties(cart,orderItem);

                        // 购买数量
                        orderItem.setBuyCounts(Integer.valueOf(cart.getCartNum()));

                        //商品总金额
                        BigDecimal productTotal = BigDecimal.valueOf(Long.valueOf(cart.getCartNum()))
                                .multiply(cart.getProductPrice());

                        orderItem.setTotalAmount(productTotal);

                        // 加入购物车时间
                        String cartTime = cart.getCartTime();
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                        Date buyTime = null;
                        try {
                            buyTime = simpleDateFormat.parse(cartTime);
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        orderItem.setBasketDate(buyTime);

                        // 购买时间
                        orderItem.setBuyTime(new Date());

                        // 评论状态
                        orderItem.setIsComment(0);

                        return orderItem;
                    }
                }).collect(Collectors.toList());


        orderItemService.saveBatch(orderItemList); // 批量入库

        //5. 删除用户购物车中的cids对应数据
        shoppingCartService.removeBatchByIds(Arrays.asList(cids));

        //6. 跟微信支付平台交互，获取可以支付的url
        String payUrl = getWxPayUrl(orderId,orders.getActualAmount(),productNames);

        //7. 组织返回的map数据
        final HashMap<String, Object> map = new HashMap<>();
        map.put("orderId",orderId);
        map.put("productNames",productNames);
        map.put("payUrl",payUrl);

        return map;

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String status(String oid) throws Exception {

        //1. 调用微信接口，查询订单状态
        String orderStatus = WxPayUtils.getOrderStatus(oid);

        //2. 如果支付成功，修改数据库orders表的status字段
        if ("SUCCESS".equals(orderStatus)){
            Orders orders = new Orders();
            orders.setOrderId(oid);
            orders.setStatus("2");  // 修改订单状态为 待发货
            this.updateById(orders);
            return "2"; // 前端约定，成功支付后需要返回的状态标识为2
        }

        return orderStatus;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void paySuccess(String orderId) throws IOException {

        //1. 更新orders表的支付状态
        Orders orders = new Orders();
        orders.setOrderId(orderId);
        orders.setStatus("2");  // 修改订单状态为 待发货
        this.updateById(orders);

        //2. 通知支付页面 （websockt）
        OrderStatusWebSocket.sendMsg(orderId,"1");

    }

    // 调用微信支付接口，获取可以支付的url
    private String getWxPayUrl(String oid,Integer totalAmout,String prodDesc) throws Exception {

        String payUrl = WxPayUtils.getPayUrl(oid, totalAmout, prodDesc);
        return payUrl;
    }

    /**
     * 检查库存是否足够，如果库存足够，就口径库存
     * @param shoppingCartList
     */
    private void checkStock(List<ShoppingCart> shoppingCartList) {

        for (ShoppingCart shoppingCart : shoppingCartList) {

            String cartNum = shoppingCart.getCartNum();
            Integer stock = shoppingCart.getStock();
            if (Integer.valueOf(cartNum)>stock){
                // 库存不足
                throw new RuntimeException(shoppingCart.getSkuName()+ "库存不足了");
            }

            // 库存扣减
            int remainStock = stock - Integer.valueOf(cartNum);
            ProductSku productSku = new ProductSku();
            productSku.setSkuId(shoppingCart.getSkuId()); // 设置id
            productSku.setStock(remainStock); // 设置要更新的库存量
            productSkuMapper.updateById(productSku);

        }

    }
}
